package ee.reliability.tool.logic;

// p = e ^ - l * t, l = 1/m - avg


import java.util.ArrayList;
import java.util.List;

import org.joda.time.DateTime;
import org.joda.time.Days;

import ee.reliability.tool.parser.Period;

public class CalculateLogic {

    private final DateTime toDate;
    private double averageTime;
    private List<Point> points;
    private final List<Period> periods;

    public CalculateLogic(DateTime toDate,List<Period> periods){
        this.toDate = toDate;
        this.periods = periods;
    }

    public List<Point> getCalculatedPoints() {
        points = new ArrayList<Point>();
        for(int i = 0;i<getDays();i++)
			points.add(getPoint(i));
        return points;
    }

    public double getTotalWorkingHours(){
        double totalWorkingHours = 0.0;
        for(Period p : getPeriods())
			if(Period.PeriodType.WORKING.equals(p.getPeriodType())) totalWorkingHours += p.getRealHours();
        return totalWorkingHours;
    }

    public double getTotalSickHours(){
        double totalSickHours = 0.0;
        for(Period p : getPeriods())
			if(Period.PeriodType.SICK.equals(p.getPeriodType())) totalSickHours += p.getRealHours();
        return totalSickHours;
    }

    private int getWorkingPeriods(){
        int counter = 0;
        for(Period p : getPeriods())
			if(Period.PeriodType.WORKING.equals(p.getPeriodType())) counter++;
        return counter;
    }

    private int getSickPeriods() {
        return getPeriods().size()-getWorkingPeriods();
    }

    public double getAvgWorkTime(){
        return getTotalWorkingHours() / getWorkingPeriods();
    }

    public double getAvgSickTime(){
        return getTotalSickHours() / getSickPeriods();
    }
    private Point getPoint(int dayCount){
        return new Point(dayCount,getResultFromFormula(dayCount));
    }

    private int getDays(){
        return Days.daysBetween(new DateTime(),toDate).getDays();
    }

    private double getResultFromFormula(double days){
        return Math.pow(Math.E,(-(1/averageTime)*days));
    }


    public List<Period> getPeriods() {
        return periods;
    }
}
